﻿////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// <copyright>Copyright 2008-2011 Andreas Huber Doenni</copyright>
// Distributed under the GNU General Public License version 2 (GPLv2).
// See accompanying file License.txt or copy at http://phuse.codeplex.com/license.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace Phuse.Net.Forums
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis;
    using System.IO;

    /// <summary>Represents an inbound forum article.</summary>
    /// <threadsafety static="true" instance="false"/>
    public interface IInboundArticle
    {
        /// <summary>Gets the group to which this article belongs.</summary>
        IGroup Group
        {
            get;
        }

        /// <summary>Gets the number of the article.</summary>
        long Number
        {
            get;
        }

        /// <summary>Gets the date of the article.</summary>
        /// <value>The body of the Date header field, if the article has one; otherwise <c>null</c>.</value>
        DateTime? DateUtc
        {
            get;
        }

        /// <summary>Gets the body of the From header field of the article.</summary>
        /// <value>The body of the From header field, if the article has one; otherwise <c>null</c>.</value>
        string From
        {
            get;
        }

        /// <summary>Gets the subject of the article.</summary>
        /// <value>The body of the Subject header field, if the article has one; otherwise <c>null</c>.</value>
        string Subject
        {
            get;
        }

        /// <summary>Gets a value indicating whether the full article has been received.</summary>
        /// <value>The value <c>true</c> if the full article has been received; otherwise, <c>false</c>.</value>
        bool HasFullArticleBeenReceived
        {
            get;
        }

        /// <summary>Gets or sets a value indicating whether the article has attachments.</summary>
        /// <value>The value <c>true</c> if the article has at least one attachment; <c>false</c> if the article has no
        /// attachments; <c>null</c> if the status is unknown.</value>
        /// <exception cref="InvalidOperationException">Set a value after <see cref="Cache.Dispose"/> has been called
        /// on the parent <see cref="Cache"/> object, or, set a value after
        /// <see cref="IDeletablePersistentObject.Delete"/> has been called on the parent <see cref="IGroup"/> or
        /// <see cref="IHost"/> objects.</exception>
        bool? HasAttachments
        {
            get;
            set;
        }

        /// <summary>Gets or sets a value indicating whether the article is currently being watched.</summary>
        /// <exception cref="InvalidOperationException">Set a value after <see cref="Cache.Dispose"/> has been called
        /// on the parent <see cref="Cache"/> object, or, set a value after
        /// <see cref="IDeletablePersistentObject.Delete"/> has been called on the parent <see cref="IGroup"/> or
        /// <see cref="IHost"/> objects.</exception>
        bool IsBeingWatched
        {
            get;
            set;
        }

        /// <summary>Gets or sets a value indicating whether this article is currently expanded.</summary>
        /// <exception cref="InvalidOperationException">Set a value after <see cref="Cache.Dispose"/> has been called
        /// on the parent <see cref="Cache"/> object, or, set a value after
        /// <see cref="IDeletablePersistentObject.Delete"/> has been called on the parent <see cref="IGroup"/> or
        /// <see cref="IHost"/> objects.</exception>
        bool IsExpanded
        {
            get;
            set;
        }

        /// <summary>Gets or sets a value indicating whether this article has been read.</summary>
        /// <exception cref="InvalidOperationException">Set a value after <see cref="Cache.Dispose"/> has been called
        /// on the parent <see cref="Cache"/> object, or, set a value after
        /// <see cref="IDeletablePersistentObject.Delete"/> has been called on the parent <see cref="IGroup"/> or
        /// <see cref="IHost"/> objects.</exception>
        bool HasBeenRead
        {
            get;
            set;
        }

        /// <summary>Gets or sets a value indicating whether this article is selected.</summary>
        /// <exception cref="InvalidOperationException">Set a value after <see cref="Cache.Dispose"/> has been called
        /// on the parent <see cref="Cache"/> object, or, set a value after
        /// <see cref="IDeletablePersistentObject.Delete"/> has been called on the parent <see cref="IGroup"/> or
        /// <see cref="IHost"/> objects.</exception>
        bool IsSelected
        {
            get;
            set;
        }

        /// <summary>Gets the article content as a stream.</summary>
        /// <returns>A <see cref="Stream"/> object containing either:
        /// <list type="bullet">
        /// <item>nothing, if <see cref="HasFullArticleBeenReceived"/> is <c>false</c>, or</item>
        /// <item>the full article, if <see cref="HasFullArticleBeenReceived"/> is <c>true</c>.</item>
        /// </list></returns>
        /// <exception cref="InvalidOperationException"><list type="bullet">
        /// <item><see cref="Cache.Dispose"/> has been called on the parent <see cref="Cache"/> object, or</item>
        /// <item><see cref="IDeletablePersistentObject.Delete"/> has been called on the parent <see cref="IGroup"/> or
        /// <see cref="IHost"/> objects, or</item>
        /// </list></exception>
        /// <remarks>The caller is responsible for properly disposing the returned object.</remarks>
        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This is an expensive operation.")]
        Stream GetContent();

        /// <summary>Gets the articles that directly follow up this one.</summary>
        /// <exception cref="InvalidOperationException"><list type="bullet">
        /// <item><see cref="Cache.Dispose"/> has been called on the parent <see cref="Cache"/> object, or</item>
        /// <item><see cref="IDeletablePersistentObject.Delete"/> has been called on the parent <see cref="IGroup"/> or
        /// <see cref="IHost"/> objects.</item>
        /// </list></exception>
        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This is an expensive operation.")]
        IEnumerable<IInboundArticle> GetFollowupInboundArticles();
    }
}
